package com.example.netty;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.buffer.Unpooled;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.util.CharsetUtil;

public class NettyServerExample {

    public static void main(String[] args) throws InterruptedException {
        // Boss group 用于接收连接，Worker group 用于处理 I/O 事件
        EventLoopGroup bossGroup = new NioEventLoopGroup(1);  // 一个线程用于处理连接
        EventLoopGroup workerGroup = new NioEventLoopGroup(); // 默认线程数处理 I/O

        try {
            // 创建服务器引导类
            ServerBootstrap bootstrap = new ServerBootstrap();
            bootstrap.group(bossGroup, workerGroup) // 绑定两个线程组
                    .channel(NioServerSocketChannel.class) // 使用NIO通道
                    .childHandler(new ChannelInitializer<SocketChannel>() { // 初始化每个客户端连接
                        @Override
                        public void initChannel(SocketChannel ch) {
                            ch.pipeline().addLast(new SimpleServerHandler()); // 添加处理器
                        }
                    });

            // 绑定端口并启动服务器
            ChannelFuture future = bootstrap.bind(8080).sync();
            System.out.println("Server started on port 8080");

            // 等待服务器 socket 关闭
            future.channel().closeFuture().sync();
        } finally {
            // 优雅关闭线程组
            bossGroup.shutdownGracefully();
            workerGroup.shutdownGracefully();
        }
    }
}

// 定义处理类，负责处理客户端消息
class SimpleServerHandler extends ChannelInboundHandlerAdapter {

    // 当客户端发送消息时，读取消息
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) {
        System.out.println("Received message: " + msg);
        // 回复客户端
        ctx.writeAndFlush(Unpooled.copiedBuffer("Hello, Client!", CharsetUtil.UTF_8));
    }

    // 异常处理
    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
        cause.printStackTrace();
        ctx.close(); // 关闭连接
    }
}

